﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Javascript AJAX API</title>
<link type="text/css" rel="stylesheet" href="../bootstrap.min.css" />
</head>

<body>

<div class="document-contents">

<h3>Problems of AJAX Operations</h3>
<p>Performing an AJAX call is frequently used by modern applcations. Especially 
in SPAs (Single-Page Applications), it's almost the only way of communicating 
with the server. An AJAX call consists of some repeating steps:</p>
<p>In client side, basically, javascript code should supply a URL, optionally a 
data and select a method (POST, GET...) to perfom an AJAX call. It must wait and 
handle the return value. There may be an error (network error generally) while 
performing call to the server. Or there may be some error in server side and server 
may send an failed response with an error message. Client code should handle 
these and optionally notify user (may show an error dialog). If there is no error and 
server sent a return data, client must also handle it. Also, generally you want 
to block 
some (or whole) area of the screen and show a busy indicator until AJAX 
operation complete.</p>
<p>Server code should get the request, perform some server-side code, catch any 
exceptions and return a valid response to the client. In an error situation, it 
may optionally send an error message to the client. If it's a validation error, 
server may want to add validation problems. In success case, it may send a 
return value to the client.</p>
<h3>ASP.NET Boilerplate Way</h3>
<p>ASP.NET Boilerplate automates some of these steps by wrapping AJAX calls with
<strong>abp.ajax</strong> function. An example ajax call:</p>
<pre lang="js">var newPerson = {
    name: 'Dougles Adams',
    age: 42
};

abp.ajax({
    url: '/People/SavePerson',
    data: JSON.stringify(newPerson)
}).done(function(data) {
    abp.notify.success('created new person with id = ' + data.personId);
});</pre>
<p>abp.ajax gets <strong>options</strong> as an object. You can pass any 
parameter that is valid in jQuery's
<a href="http://api.jquery.com/jQuery.ajax/" target="_blank">$.ajax</a> method. 
There are some <strong>defaults</strong> here: dataType is '<strong>json</strong>', 
type is '<strong>POST</strong>' and contentType is '<strong>application/json</strong>' 
(So, we're calling JSON.stringify to convert javascript object to JSON string 
before sending to the server). You can override 
defaults by passing options to abp.ajax.</p>
<p>abp.ajax returns <strong>
<a href="http://api.jquery.com/deferred.promise/" target="_blank">promise</a></strong>. So, you can write done, fail, then... handlers. In 
this example, we made a simple AJAX request to <strong>PeopleController</strong>'s
<strong>SavePerson</strong> action. In the <strong>done </strong>handler, we got the database
<strong>id</strong> for the new created person and showing a success notification (See
<a href="/Pages/Documents/Javascript-API/Notification">notification API</a>). Let's see the <strong>MVC controller</strong> for this AJAX call:</p>
<pre lang="cs">public class PeopleController : <strong>AbpController</strong>
{
    <strong>[HttpPost]</strong>
    public <strong>JsonResult</strong> SavePerson(SavePersonModel person)
    {
        //TODO: save new person to database and return new person's id
        <strong>return Json(new {PersonId = 42});</strong>
    }
}</pre>
<p><strong>SavePersonModel</strong> contains Name and Age properties as you can guess. 
SavePerson is marked with <strong>HttpPost</strong> since abp.ajax's default 
method is POST. I simplified method implemtation by returning an anonymous 
object.</p>
<p>This seams straightforward, but there are some important things behind the 
scenes that is handled by ASP.NET Boilerplate. Let's dive into details...</p>
<h4>AJAX Return Messages</h4>
<p>Even we directly return an object with PersonId = 2, ASP.NET 
Boilerplate wraps it by an <strong>MvcAjaxResponse</strong> object. Actual 
AJAX response is something like that:</p>
<pre lang="cs">{
  "success": true,
  "result": {
    "personId": 42
  },
  "error": null,
  "targetUrl": null,
  "unAuthorizedRequest": false,
  "__abp": true
}</pre>
<p>Here, all properties are camelCase (since it's conventional in javascript 
world) even they are PascalCase in the server code. Let's explain all fields:</p>
<ul>
	<li><strong>success</strong>: A boolean value (true or false) that indicates 
	success status of the operation. If this is true, abp.ajax resolves the 
	promise and calls the <strong>done</strong> handler. If it's false (if there 
	is an exception thrown in method call), it calls
	<strong>fail</strong> handler and shows the <strong>error</strong> message 
	using <a href="/Pages/Documents/Javascript-API/Message">abp.message.error</a> 
	function.</li>
	<li><strong>result</strong>: Actual return value of the controller action. 
	It's valid if success is true and server sent a return value.</li>
	<li><strong>error</strong>: If success is false, this field is an object 
	that contains <strong>message</strong> and <strong>details</strong> fields.</li>
	<li><strong>targetUrl</strong>: This provides a possibility to the server to
	<strong>redirect</strong> client to another url if needed.</li>
	<li><strong>unAuthorizedRequest</strong>: This provides a possibility to the 
	server to inform client that this operation is not authorized or user is not 
	authenticated. abp.ajax <strong>reloads</strong> current page if this is 
	true.</li>
	<li><strong>__abp</strong>: A special signature that is returned by ABP 
	wrapped responses. You don't use this yourself, but abp.ajax handles it.</li>
</ul>
<p>This return format is recognized and handled by <strong>
abp.ajax</strong> function. Your done handler in 
abp.ajax gets the actual return value of the controller (An object with personId 
property) if there is no error.</p>
<h4>Handling Errors</h4>
<p>As described above, ASP.NET Boilerplate handles exceptions in server and 
returns an object with an error message like that:</p>
<pre lang="js">{
  "targetUrl": null,
  "result": null,
  "success": false,
  "error": {
    "message": "An internal error occured during your request!",
    "details": "<span lang="tr">...</span>"
  },
  "unAuthorizedRequest": false,
  "__abp": true
}</pre>
<p>As you see, <strong>success is false</strong> and <strong>result is null</strong>. 
abp.ajax handles this object and shows an error message to the user using
<a href="/Pages/Documents/Javascript-API/Message">abp.message.error</a> 
function. If your server side code throws an exception type of 
<strong>UserFriendlyException</strong>, it directly shows exception's message to the user. 
Otherwise, it hides the actual error (writes error to logs) and shows a standard 
''An internal error occured..." message to the user. All these are automatically 
done by ASP.NET Boilerplate.</p>
	<p>You may want to disable displaying message for particular AJAX call. Then 
	add <strong>abpHandleError: false</strong> into abp.ajax options.</p>
	<h5>HTTP Status Codes</h5>
	<p>ABP returns given HTTP status codes on exceptions:</p>
	<ul>
		<li><strong>401</strong> for unauthenticated requests (Used has not 
		logged in but server action needs authentication).</li>
		<li><strong>403</strong> for unauthorized requests.</li>
		<li><strong>500</strong> for all other exception types.</li>
	</ul>
<h4>WrapResult and DontWrapResult Attributes</h4>
<p>You can control wrapping using <strong>WrapResult</strong> and <strong>
DontWrapResult</strong> attributes for an action or all actions of a controller.</p>
<h5>ASP.NET MVC Controllers</h5>
<p>ASP.NET Boilerplate <strong>wraps</strong> (as described above) ASP.NET
<strong>MVC</strong> action results <strong>by default</strong> if return type 
is <strong>JsonResult</strong> (or Task&lt;JsonResult&gt; for async actions). You can 
change this by using <strong>WrapResult</strong> attribute as shown below:</p>
<pre>public class PeopleController : AbpController
{
    [HttpPost]
    <strong>[WrapResult(WrapOnSuccess = false, WrapOnError = false)]</strong>
    public JsonResult SavePerson(SavePersonModel person)
    {
        //TODO: save new person to database and return new person's id
        return Json(new {PersonId = 42});
    }
}</pre>
<p>As a shortcut, we can only use <strong>[DontWrapResult]</strong> which is 
identical for this example.</p>
	<p>You can change this default behaviour from
	<a href="../Startup-Configuration.html">startup configuration</a> (using 
	Configuration.Modules.AbpMvc()...).</p>
<h5>ASP.NET Web API Controllers</h5>
<p>ASP.NET Boilerplate <strong>does not wrap</strong> Web API actions <strong>by 
default</strong> if action has successfully executed. You can add WrapResult to actions or controllers if you need.&nbsp;But 
it <strong>wraps exceptions</strong>.</p>
	<p>You can change this default behaviour from
	<a href="../Startup-Configuration.html">startup configuration</a> (using 
	Configuration.Modules.AbpWebApi()...).</p>
<h5>Dynamic Web API Layer</h5>
<p>ASP.NET Boilerplate <strong>wraps</strong> dynamic web api layer methods
<strong>by default</strong>. You can change this behaviour using <strong>
WrapResult </strong>and <strong>DontWrapResult </strong>attributes in the
<strong>interface</strong> of your application service.</p>
	<p>You can change this default behaviour from
	<a href="../Startup-Configuration.html">startup configuration</a> (using 
	Configuration.Modules.AbpWebApi()...).</p>
	<h5>ASP.NET Core Controllers</h5>
	<p>ABP automatically wraps results for JsonResult, ObjectResult and any 
	object which does not implement IActionResult.&nbsp; See
	<a href="../AspNet-Core.html">ASP.NET Core documentation</a> for more.</p>
	<p>You can change this default behaviour from
	<a href="../Startup-Configuration.html">startup configuration</a> (using 
	Configuration.Modules.AbpAspNetCore()...).</p>

<h4>Dynamic Web API Layer</h4>
<p>While ASP.NET Boilerplate provides a mechanism to make easy AJAX calls, in a 
real world application it's typical to write a javascript function for every 
AJAX call. For example:</p>
<pre lang="js">//Create a function to abstract AJAX call
var savePerson = function(person) {
    return abp.ajax({
        url: '/People/SavePerson',
        data: JSON.stringify(person)
    });
};

//Create a new person
var newPerson = {
    name: 'Dougles Adams',
    age: 42
};

//Save the person
savePerson(newPerson).done(function(data) {
    abp.notify.success('created new person with id = ' + data.personId);
});</pre>
<p>This is a good practice but time-consuming and tedious to write a function 
for every ajax call. ASP.NET can automatically generate 
these type of functions for <a href="/Pages/Documents/Application-Services">
application service</a> and controllers.</p>
	<p>Read the
<a href="/Pages/Documents/Dynamic-Web-API">dynamic web api</a> layer 
documentation for Web API and ASP.NET Core documentation for
	<a href="../AspNet-Core.html">ASP.NET Core</a> integration.</p>

</div>

</body>

</html>
